package util;


import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.*;

/**
 * @author: zen
 * @date: 2020/4/12
 * @Title: DBUtilImpl
 * @Description: 使用双重检查单例模式
 */
public class DBUtilImpl implements DBUtil {

    /**
     *  使用数据源技术
     */
    private static DataSource ds = null;

    private volatile static DBUtilImpl dbUtil = null;

    private DBUtilImpl(){};

    public static DBUtilImpl getSingleton() {
        if (dbUtil == null) {
            synchronized (DBUtilImpl.class) {
                if (dbUtil == null) {
                    dbUtil = new DBUtilImpl();
                }
            }
        }
        return dbUtil;
    }

    public static DataSource getDataSource() throws Exception {
        long start = System.currentTimeMillis();
        if (ds == null) {
            // 初始化上下文
            Context initContext = new InitialContext();
            if (initContext == null) {
                throw new Exception("No Context");
            }
            // 根据协议名查找数据源
            Context envContext = (Context) initContext.lookup("java:/comp/env");
            // 根据数据源的逻辑名称查找数据源，必须与Tomcat中的Context.xml配置一致
            ds = (DataSource) envContext.lookup("jdbc/gourmetDB");
            long end = System.currentTimeMillis();
            System.out.println("测试数据库连接时间：" + (end - start));
        }
        return ds;
    }

    /**
     * 通过数据源获取连接
     * @return 连接对象
     */
    @Override
    public  Connection getConnection() {
        try {
            Connection conn = getDataSource().getConnection();
            if (conn != null) {
                return conn;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 关闭连接
     * @param conn
     * @param pstmt
     * @param rs
     */
    @Override
    public  void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
